package com.hsqyz.esp32_led.factory;

import com.hsqyz.esp32_led.factory.processor.IMessageProcessor;
import com.hsqyz.esp32_led.model.dto.Esp32MessageDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;

/**
 * 消息处理器工厂
 * 
 * 该类负责管理和分发不同类型的消息处理器，主要功能包括：
 * 1. 消息处理器注册：支持动态注册不同类型的消息处理器
 * 2. 消息处理：根据消息类型选择对应的处理器进行处理
 * 3. 异常处理：统一处理消息处理过程中的异常
 * 
 * 使用ConcurrentHashMap确保线程安全，支持高并发场景
 */
@Slf4j
@Component
public class MessageProcessorFactory {

    /**
     * 消息处理器映射表
     * key: 消息类型（命令）
     * value: 对应的消息处理器
     */
    private final ConcurrentHashMap<String, IMessageProcessor> messageProcessorMap = new ConcurrentHashMap<>();

    /**
     * 接收并处理消息
     * 
     * 根据消息类型选择对应的处理器进行处理。
     * 如果找不到对应的处理器，记录错误日志。
     * 处理过程中的异常会被捕获并记录。
     *
     * @param messageDto 待处理的消息对象
     */
    public void acceptMessage(Esp32MessageDto messageDto) {
        // 获取消息处理器
        IMessageProcessor messageProcessor = messageProcessorMap.get(messageDto.getCmd());
        if (messageProcessor == null) {
            log.error("适配器处理: {}，命令不存在", messageDto.getCmd());
            return;
        }
        try {
            // 调用处理器处理消息
            messageProcessor.messageOp(messageDto);
        } catch (Exception e) {
            log.error("适配器处理: {}，命令异常:{}", messageDto.getCmd(), e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 注册消息处理器
     * 
     * 将消息处理器添加到管理器中，如果已存在相同类型的处理器，
     * 则不会覆盖原有的处理器。
     *
     * @param key 消息类型（命令）
     * @param messageProcessor 消息处理器实例
     * @throws IllegalArgumentException 如果key或messageProcessor为null
     */
    public void put(String key, IMessageProcessor messageProcessor) {
        // 参数校验
        if (key == null || messageProcessor == null) {
            throw new IllegalArgumentException("Neither 'key' nor 'messageProcessor' can be null.");
        }

        try {
            // 使用putIfAbsent确保不会覆盖已存在的处理器
            messageProcessorMap.putIfAbsent(key, messageProcessor);
        } catch (Exception e) {
            // 记录异常信息
            System.err.println("Failed to put message processor: " + e.getMessage());
        }
    }
}
